package com.sugon.controller.analyse;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.sugon.annotation.DataFilter;
import com.sugon.dao.DevMaintenWorkDao;
import com.sugon.dao.DevMaintenanceTicketDao;
import com.sugon.dao.DeviceInfoDao;
import com.sugon.entity.SysDeptEntity;
import com.sugon.modules.analyse.model.vo.DevAlarmTimeTopStatVO;
import com.sugon.modules.analyse.model.vo.FaultHandleDurationTopWorkVO;
import com.sugon.modules.analyse.service.IDeviceAnalyseService;
import com.sugon.modules.device.consts.enums.DevMaintenanceTicketStatusEnum;
import com.sugon.modules.device.consts.enums.DevRepairTicketStatusEnum;
import com.sugon.modules.device.model.vo.DeviceTicketStatVO;
import com.sugon.service.SysDeptService;
import com.sugon.utils.PageUtils;
import com.sugon.utils.R;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @description: 设备统计分析Controller
 * @author: YuXD
 * @create: 2020-05-10 17:08
 **/
@RestController
@RequestMapping("device/stat")
public class DeviceAnalyseController {

    @Autowired
    private IDeviceAnalyseService deviceAnalyseService;
    @Autowired
    private DeviceInfoDao deviceInfoDao;
    @Autowired
    private IDeviceAnalyseService iDeviceAnalyseService;
    @Autowired
    private SysDeptService deptService;
    @Autowired
    private DevMaintenanceTicketDao devMaintenanceTicketDao;
    @Autowired
    private DevMaintenWorkDao devMaintenWorkDao;

    /**
     * 设备故障处理时间段统计分析
     * 设备报表-维修工单处理时长分析
     */
    @RequestMapping("/ticket")
    public R getWorkshopTicketStat(@RequestParam String workshopCode) {
        SysDeptEntity dept = deptService.getByDCode(workshopCode);
        if (dept == null) {
            return R.error("非法组织代码！");
        }
        List<DeviceTicketStatVO> ticketList = new ArrayList<>();
        // 获取并设置进行中的设备维护工单列表
        List<DeviceTicketStatVO> ingMaintenanceTicketList = devMaintenanceTicketDao.statIngDeviceTicketByDeptId(dept.getDeptId());
        if (CollectionUtil.isNotEmpty(ingMaintenanceTicketList)) {
            Map<Integer, DevMaintenanceTicketStatusEnum> maintenanceTicketStatusMap = DevMaintenanceTicketStatusEnum.map();
            ingMaintenanceTicketList.forEach(ingMaintenanceTicket -> {
                // 设置状态描述
                String statusDesc = maintenanceTicketStatusMap.get(ingMaintenanceTicket.getStatus()).getDesc();
                if (StrUtil.isEmpty(statusDesc)) {
                    statusDesc = "未知";
                }
                ingMaintenanceTicket.setStatusDesc(statusDesc);
                ingMaintenanceTicket.setTicketType("维护");
            });
        }
        ticketList.addAll(ingMaintenanceTicketList);
        // 获取并设置尚未完成的设备维修工单列表
        List<DeviceTicketStatVO> ingRepairTicketList = devMaintenWorkDao.statIngDeviceTicketByDeptId(dept.getDeptId());
        if (CollectionUtil.isNotEmpty(ingRepairTicketList)) {
            Map<Integer, DevRepairTicketStatusEnum> repairTicketStatusMap = DevRepairTicketStatusEnum.map();
            ingRepairTicketList.forEach(ingRepairTicket -> {
                String statusDesc = repairTicketStatusMap.get(ingRepairTicket.getStatus()).getDesc();
                if (StrUtil.isEmpty(statusDesc)) {
                    statusDesc = "未知";
                }
                ingRepairTicket.setStatusDesc(statusDesc);
                ingRepairTicket.setTicketType("维修");
            });
        }
        ticketList.addAll(ingRepairTicketList);
        // 按照工作时长降序排列
        ticketList.sort((o1, o2) -> (int) (o2.getCallRepairDuration() - o1.getCallRepairDuration()));
        PageUtils pageUtil = new PageUtils(ticketList, ticketList.size(), 100, 1);
        return R.ok().put("page", pageUtil);
    }

    /**
     * 对当前设备组织下的维修和维护工单中不同状态下的工单数统计
     */
    @GetMapping("/maintainNum")
    public R deptMaintainNumStat(@RequestParam("lineCode") String lineCode) {
        return R.ok().put("deptStat", deviceAnalyseService.deptMaintainNumStat(lineCode));
    }

    /**
     * 设备故障处理时间段统计分析
     * 设备报表-维修工单处理时长分析
     */
    @RequestMapping("/faultHandleDuration")
    public R faultHandleDuration(@RequestBody Map<String, Object> param) {
        return R.ok().put("result", deviceAnalyseService.getWorkExecuteAvgStat(param));
    }

    /**
     * 故障处理时长TOP工单统计
     * 按照接单、维修和效果确认三个维度处理
     */
    @RequestMapping("/faultHandleDurationTopWork")
    public R faultHandleDurationTopWork(@RequestParam Map<String, Object> param) {
        List<FaultHandleDurationTopWorkVO> devMaintenWorkList = deviceAnalyseService.faultHandleDurationTopWorkStat(param);
        PageUtils pageUtil = new PageUtils(devMaintenWorkList, 10, 10, 1);
        return R.ok().put("page", pageUtil);
    }

    /**
     * 设备故障处理时间段统计分析
     * 设备报表-维修工单处理时长分析
     */
    @RequestMapping("/faultDurationAnalyse")
    public R faultDurationAnalyse(@RequestBody Map<String, Object> param) {
        return R.ok().put("result", deviceAnalyseService.getFaultDurationStat(param));
    }

    /**
     * 统计发生故障的前top次的设备名称和次数
     *
     * @return
     */
    @RequestMapping("/topFault")
    public R topFault(@RequestBody Map<String, Object> param) {
        return R.ok().put("topFaultDev", deviceAnalyseService.doDevFaultTopStat(param));
    }

    /**
     * 设备PM工单数量分布统计
     * 首页用
     */
    @DataFilter(deptAlias = "DMT.WORKSHOP", userAlias = "DMT.EXECUTOR")
    @RequestMapping("/pmTicketNumDistribution")
    public R statPmTicketNumDistribution(@RequestBody Map<String, Object> param) {
        return R.ok().put("statResult", deviceAnalyseService.doStatDevPmTicketNumDistribution(param));
    }

    /**
     * 设备AM工单数量分布统计
     * 首页用
     */
    @DataFilter(deptAlias = "DMT.WORKSHOP", userAlias = "DMT.EXECUTOR")
    @RequestMapping("/amTicketNumDistribution")
    public R statAmTicketNumDistribution(@RequestBody Map<String, Object> param) {
        return R.ok().put("statResult", deviceAnalyseService.doStatDevAmTicketNumDistribution(param));
    }

    /**
     * 设备维修工单数量分布统计
     * 首页用
     */
    @RequestMapping("/repairTicketNumDistribution")
    public R statRepairTicketNumDistribution(@RequestBody Map<String, Object> param) {
        return R.ok().put("statResult", deviceAnalyseService.doStatDevRepairTicketNumDistribution(param));
    }

    /**
     * 统计设备故障分类次数和累计百分比
     *
     * @return
     */
    @RequestMapping("/faultTypeTimeAndRate")
    public R statDevFaultTypeTimeAndRate(@RequestParam(required = false) String month) {
        return R.ok().put("devFaultTypeTimeStat", deviceAnalyseService.statDevFaultTypeTimeAndRate(month));
    }

    /**
     * 统计指定设备区域下故障发生次数
     * 设备报表-区域设备故障次数统计报表
     */
    @RequestMapping("/areaFaultTime")
    public R statAreaDeviceFaultTime(@RequestParam(required = false, value = "dcode") String dcode, @RequestParam(required = false, value = "month") String month) {
        return R.ok().put("result", deviceAnalyseService.doAreaDeviceFaultTimeStat(dcode, month));
    }

    /**
     * 统计指定设备区域下故障发生次数
     * 设备报表-人员维修工作量统计
     */
    @RequestMapping("/repairWork")
    public R statRepairWork(@RequestBody Map<String, Object> params) {
        // 默认当前月份
        if (!params.containsKey("month")) {
            params.put("month", DateUtil.format(DateUtil.date(), DatePattern.NORM_MONTH_PATTERN));
        }
        return R.ok().put("result", deviceAnalyseService.doRepairWorkStat(params));
    }

    /**
     * 统计不同运行状态下的设备数
     */
    @RequestMapping("/status")
    public R statDevStatusNum(@RequestBody Map<String, Object> params) {
        return R.ok().put("devStatusStat", deviceAnalyseService.statDevStatusNum(params));
    }

    /**
     * 统计基地中设备PM完成情况
     * 分为完成和延期两种状况，一般只要未完成的都算延期
     */
    @RequestMapping("/pmCompleteRate")
    public R statDevPmCompleteRate(@RequestBody Map<String, Object> params) {
        return R.ok().put("devStatusStat", deviceAnalyseService.statDevPmCompleteRate(params));
    }

    /**
     * 统计设备的报警和维修对比
     *
     * @return
     */
    @RequestMapping("/alarmRepairCompare")
    public R statDeviceAlarmRepairCompare(@RequestBody Map<String, Object> params) {
        return R.ok().put("compareStat", deviceAnalyseService.statDeviceAlarmRepairCompare(params));
    }

    /**
     * 统计设备运行报警时长和频次统计
     *
     * @return
     */
    @RequestMapping("/devAlarmTimeAndRate")
    public List<DevAlarmTimeTopStatVO> statDevAlarmTimeAndRate(@RequestBody(required = false) Map<String, Object> params) {
        return deviceAnalyseService.statDeviceAlarmTimeTop(params);
    }

    /**
     * 获取设备指定参数的趋势折线图
     *
     * @return
     */
    @RequestMapping("/paramLineData")
    public R loadDeviceParamLineData(@RequestBody Map<String, Object> params) {
        return R.ok().put("paramLineData", deviceAnalyseService.loadDeviceParamLineData(params));
    }

    /**
     * 统计设备报警时长TOP统计
     *
     * @return
     */
    @RequestMapping("/alarmTimeTop")
    public R statDeviceAlarmTimeTop(@RequestBody Map<String, Object> params) {
        return R.ok().put("compareStat", deviceAnalyseService.statDeviceAlarmTimeTop(params));
    }

    /**
     * 加载设备列表
     *
     * @param deptId 车间组织ID
     * @return
     */
    @GetMapping("/devList")
    public R loadDevList(@RequestParam String deptId) {
        List<Map<String, Object>> devList = deviceInfoDao.loadDevList(deptId);
        return R.ok().put("devList", devList);
    }

    /**
     * 加载设备参数列表
     *
     * @param devCode 设备编码
     * @return
     */
    @GetMapping("/devParamList")
    public R loadDevParamList(@RequestParam String devCode) {
        return R.ok().put("devParamList", deviceAnalyseService.loadDevParamList(devCode));
    }

    /**
     * 加载设备运行监控数据
     *
     * @param devCode 设备编码
     * @return
     */
    @GetMapping("/deviceMonitor")
    public R deviceMonitor(@RequestParam String devCode) {
        if (StringUtils.isBlank(devCode)) {
            return R.error("没有获取到设备码信息，请重新尝试！");
        }
        try {
            return R.ok().put("deviceMonitor", iDeviceAnalyseService.deviceMonitor(devCode));
        } catch (Exception e) {
            return R.error(e.getMessage());
        }
    }

}
